﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Text;


namespace Xant.Querier.Core
{
    public class Constant : Factor
    {
        private static readonly Type[] supportedTypes = new Type[] { typeof(string), typeof(bool), typeof(int), typeof(decimal), typeof(double), typeof(DateTime), typeof(Guid), typeof(Byte), typeof(Byte[]), };
        private static readonly Constant NullConstant = new Constant((object)null);

        public object Value { get; protected set; }

        public override string ToString()
        {
            if (Value == null)
            {
                return null;
            }
            else
            {
                var format = "{0}";
                var type = Value.GetType();
                if (type == typeof(decimal) || type == typeof(double))
                {
                    format = "{0:0.0#######}";
                }
                return string.Format(format, Value);
            }

        }

        public static Constant Null
        {
            get {  return NullConstant;}
        }

        public Constant(object value)
        {
            if (value != null)
            {
                var type = value.GetType();
                if (Array.IndexOf<Type>(supportedTypes, type) < 0)
                    throw new NotSupportedException("不支付的常量值类型："+type.FullName);
            }
            this.Value = value;
        }

        public Constant(string value)
            : this((object)value)
        {
        }

        public Constant(bool? value)
            : this((object)value)
        {
        }

        public Constant(int? value)
            : this((object)value)
        {
        }

        public Constant(decimal? value)
            : this((object)value)
        {
        }

        public Constant(double? value)
            : this((object)value)
        {
        }

        public Constant(DateTime? value)
            : this((object)value)
        {
        }

        public Constant(Guid? value)
            : this((object)value)
        {
        }

        public Constant(Byte? value)
            : this((object)value)
        {
        }

        public Constant(Byte[] value)
            : this((object)value)
        {
        }

        public override int GetHashCode()
        {
            return this.Value.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            var compare2 = obj as Constant;
            return compare2 != null && this.Value.Equals(compare2.Value);
        }

    }

    /*//这里用泛型没太大实际用处，比如创建常量的代码不能写成new Constant(value)，而必须写成new Constant<string>(value)
    //改为直接在Constant类中重载多个版本的构造函数
    public class Constant<T> : Constant
    {
        public Constant(T value):base(value)
        {
        }
    }
    */


}
